android - layer-list 属性让特殊样式变得简单

前言

在开发中,总是能碰到那种看起来很简单,但是想想又不是一两句代码就好实现的 UI 样式效果。比如前几天在调整 UI 的时候,就遇到过几个下图这样的:

1]1MPB97(OC8Z@E1WS{T`G7.png
8G(NRRT0N6IPC(_EUQ09SOG.png

这几张图里面的输入框的背景图乍一看没有什么,但是在认识 <layer-list> 之前你会怎么实现呢?比如一二两张图的输入框,看起来就只有下面一条线,当输入框没有获取焦点时显示灰色,当输入框获取焦点时显示绿色。而第二张图直接左右各多出来半截。如果是我,我估计第一张图我会用俩控件实现,第二张图直接 UI 出 .9 图(捂脸ing)。

而现在,我们可以用 <layer-list>这个属性来更优雅的实现这个效果。

初识 <layer-list>

<layer-list> 是 android 可绘制对象资源中的一种。文档 中描述:可绘制对象资源是一般概念,是指可在屏幕上绘制的图形,以及可以使用 getDrawable(int) 等 API 检索或者应用到具有 android:drawable 和 android:icon 等属性的其他 XML 资源的图形。有以下几类:

类别 描述 创建
位图文件 位图图形文件(.png、.jpg 或 .gif) BitmapDrawable
九宫格文件 具有可拉伸区域的 PNG 文件,允许根据内容调整图像大小 (.9.png) BitmapDrawable
图层列表 管理其他可绘制对象阵列的可绘制对象。它们按阵列顺序绘制,因此索引最大的元素绘制在顶部 LayerDrawable
状态列表 此 XML 文件为不同状态引用不同位图图形(例如,按下按钮时使用不同的图像) StateListDrawable
级别列表 此 XML 文件用于定义管理大量备选可绘制对象的可绘制对象,每个可绘制对象都分配有最大的备选数量 LevelListDrawable
转换可绘制对象 此 XML 文件用于定义可在两种可绘制对象资源之间交错淡出的可绘制对象 TransitionDrawable
插入可绘制对象 此 XML 文件用于定义以指定距离插入其他可绘制对象的可绘制对象。当视图需要小于视图实际边界的背景可绘制对象时,此类可绘制对象很有用 InsetDrawable
裁剪可绘制对象 此 XML 文件用于定义更改其他可绘制对象大小(根据其当前级别值)的可绘制对象 ScaleDrawable
形状可绘制对象件 此 XML 文件用于定义几何形状(包括颜色和渐变) ShapeDrawable

这么多种类,里面有几个大家都很熟悉的: 位图文件、九宫格文件 和形状可绘制对象件。就是我们平常用的 drawable、.9 图片 和 shape 文件。其它的种类我还没有接触过。今天说一下其中的图层列表

<layer-list>属性介绍

图层列表中的每个可绘制对象按照列表的顺序绘制,列表中的最后一个可绘制对象绘于顶部。
每个可绘制对象由单一 <layer-list> 元素内的 <item> 元素表示。
语法示例:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:id="@[+][package:]id/resource_name"
android:top="dimension"
android:right="dimension"
android:bottom="dimension"
android:left="dimension" />
</layer-list>

这里说一下达到复杂效果常用的几个属性:

属性 描述
android:top 顶部偏移(像素)
android:Left 左边偏移(像素)
android:Right 右边偏移(像素)
android:Bottom 底部偏移(像素)

很简单,有没有。因为就像定义所说,图层列表按顺序绘制,所以我们经常会根据设置顺序加上上下左右的偏移量来达到 ui 效果。

<layer-list>实战

首先以第一个输入框获取焦点时效果为例,其实思路很简单,就是最底层是一个绿色矩形,然后上面再盖一个灰色矩形,只不过灰色矩形距离底部 1dp 的高度,所以就达到只有底部一条绿线的效果。所以有了顺序和偏移量,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="#00BE3C" />
</shape>
</item>
<item
android:bottom="1dp">
<shape android:shape="rectangle" >
<solid android:color="#E5E5E5" />
</shape>
</item>
</layer-list>

同理,第二个输入框的效果的思路:底部是一个矩形边框,边框颜色为绿色,宽 1dp,填充白色,然后上面再盖一层白色矩形,然后让白色矩形距离底部 4dp,就实现效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<stroke android:color="#00BE3C" android:width="1dp"></stroke>
<solid android:color="#ffffff"></solid>
</shape>
</item>
<item android:bottom="4dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff"></solid>
</shape>
</item>
</layer-list>

总结

所以其实很简单,我们拿到 UI 效果后,首先要分析根据顺序每一层绘制什么,然后确定每一层的偏移量就好了

参考文章

https://developer.android.com/guide/topics/resources/drawable-resource?hl=zh-cn#LayerList


------------- 本文结束 感谢您的阅读 -------------